/*
 * $Id: UdpSocket.cc,v 1.9 2005-12-31 17:33:26 bacon Exp $
 */

#include <xpp/net/UdpSocket.h>
#include <xp/bas/errno.h>

namespace xpp
{
	namespace net
	{

		UdpSocket::UdpSocket (): InetSocket (DATAGRAM)
		{
		}	

		int UdpSocket::open (Handle handle)
		{
			return InetSocket::open (handle);
		}

		int UdpSocket::open (Handle handle, const Address& target)
		{
			return InetSocket::open (handle, target);
		}

		int UdpSocket::open (const Address& address)
		{
			return InetSocket::open (address);
		}

		int UdpSocket::connect ()
		{
			addr_t* p = target.storage();
			len_t   l = target.storageSize();

			int n = xp_sck_conn (this, p, l);
			if (n == -1) {
				error_code = translate_errno (
					XPP_NET_SOCKET_ERRNO, ERR_GENERAL);
			}

			return n;
		}

		xp_ssize_t UdpSocket::send (
			const void* data, xp_size_t size, int flags)
		{
			XPP_NET_SOCKET_CHECK_CLOSED_HANDLE (this->sckhnd);

			xp_ssize_t nn;

			nn = xp_sck_send (this, data, size, flags);
			if (nn == -1) {
				error_code = translate_errno (
					XPP_NET_SOCKET_ERRNO, ERR_GENERAL);
				return -1;
			}
		
			return nn;
		}

		xp_ssize_t UdpSocket::sendAll (
			const void* data, xp_size_t size, int flags)
		{
			this->error_code = ERR_NOSUPPORT;
			return -1;
		}

		xp_ssize_t UdpSocket::send (
			const void* data, xp_size_t size, 
			const Address& target, int flags)
		{
			XPP_NET_SOCKET_CHECK_CLOSED_HANDLE (this->sckhnd);

			xp_ssize_t nn;
			addr_t* p = target.storage();
			len_t   l = target.storageSize();

			nn = xp_sck_sendto (this, data, size, flags, p, l);
			if (nn == -1) {
				error_code = translate_errno (
					XPP_NET_SOCKET_ERRNO, ERR_GENERAL);
				return -1;
			}
		
			return nn;
		}

		xp_ssize_t UdpSocket::receive (
			void* buf, xp_size_t size, Address* addr, int flags)
		{
			XPP_NET_SOCKET_CHECK_CLOSED_HANDLE (this->sckhnd);
		
			xp_ssize_t nn;
			addr_t* p = addr->storage();
			len_t   l = addr->storageSize ();

			nn = xp_sck_recvfrom (this, buf, size, flags, p, &l);
			if (nn == -1) {
				error_code = translate_errno (
					XPP_NET_SOCKET_ERRNO, ERR_GENERAL);
				return -1;
			}
		
			return nn;
		}

		xp_ssize_t UdpSocket::receive (void* buf, xp_size_t size, int flags)
		{
			this->error_code = ERR_NOSUPPORT;
			return -1;
		}

		xp_ssize_t UdpSocket::receiveAll (void* buf, xp_size_t size, int flags)
		{
			this->error_code = ERR_NOSUPPORT;
			return -1;
		}

	}
}
